import { useState, useCallback, useRef, useEffect } from "react";
import "./App.css";
import ObserveComponent from "./ObserveComponent";

function buildThresholdList() {
  let thresholds = [];
  // let numSteps = 20;

  // for (let i=1.0; i<=numSteps; i++) {
  //   let ratio = i/numSteps;
  //   thresholds.push(ratio);
  // }

  // thresholds.push(0);
  // return thresholds;
  return 0.5;
}

let handleIntersect = (entries: any[], observer: any) => {
  entries.forEach((entry) => {
    console.log(
      // entry.boundingClientRect,
      entry.intersectionRatio,
      // entry.intersectionRect,
      entry.isIntersecting,
      // entry.rootBounds,
      entry.target,
      entry.time
    );
  });
};

/**
 * 通过 selcect DOM 做 observer，但是因为 react 还没有渲染所以查询不到
 * @param handleIntersect
 * @returns
 */
function createObserverByDomSelect(
  handleIntersect: IntersectionObserverCallback
) {
  let observer: IntersectionObserver;

  let options = {
    root: document.querySelector("#scrollArea"),
    rootMargin: "0px",
    threshold: buildThresholdList(),
  };

  observer = new IntersectionObserver(handleIntersect, options);
  let targets: NodeListOf<Element> = document.querySelectorAll(".listItem");
  targets?.forEach((item: Element) => {
    observer.observe(item);
  });
  return observer;
}

async function wsClient(doSth: Function) {
  const ws: any = await connectToServer();
  // ws.onopen = function(evt:Event) {
  //   console.log("Connection open ...");
  //   ws.send(JSON.stringify({name:'ufo'}));
  // };

  ws.onmessage = (webSocketMessage: { data: string }) => {
    doSth(JSON.parse(webSocketMessage?.data));
  };

  // document.body.onmousemove = (evt) => {
  //   const messageBody = { x: evt.clientX, y: evt.clientY };
  //   ws.send(JSON.stringify(messageBody));
  // };

  async function connectToServer() {
    const ws = new WebSocket("ws://localhost:7071");
    return new Promise((resolve, reject) => {
      const timer = setInterval(() => {
        if (ws.readyState === 1) {
          clearInterval(timer);
          resolve(ws);
          ws.send(JSON.stringify({ name: "ufo" }));
        }
      }, 1000);
    });
  }

  ws.onclose = function (evt: Event) {
    console.log("Connection closed.");
  };
}

function App() {
  const [datas, setdatas] = useState<Number[]>([]);
  const inViewData = useRef<Map<number, null>>(new Map());
  let wsData = useRef<Number[]>([]);

  let _wsClient = useCallback(wsClient, []);

  function doSth(data: Number[]) {
    // setdatas(data);
    // return
    if (inViewData.current.size === 0) {
      setdatas(data);
      wsData.current = data
      return;
    }
    let newData = [...wsData.current];
    if (inViewData.current) {
      [...inViewData.current.keys()].forEach((index) => {
        newData.splice(index, 1, data[index]);
      });
    }
    wsData.current = newData
    setdatas(newData);
  }

  useEffect(() => {
    _wsClient(doSth);
    // const ob = createObserverByDomSelect(handleIntersect);
    return () => {
      // ob.disconnect();
    };
  }, []);

  const makeBigData = () => {
    return datas.map((item, index) => {
      return (
        <ObserveComponent
          key={index}
          item={item}
          index={index}
          handleObserver={function (index, inView): void {
            if (inView) {
              inViewData.current.set(index, null);
            } else {
              inViewData.current.delete(index);
            }
          }}
        ></ObserveComponent>
      );
    });
  };

  return (
    <div className="App" id="scrollArea">
      {makeBigData()}
    </div>
  );
}

export default App;
